'use client'

import { useCallback, useEffect, useRef, useState } from "react";
import { DocInfo, ShareInfo } from "@/grpc/types";
import { Remirror, useRemirror, EditorComponent, ThemeProvider } from '@remirror/react';
import type { RemirrorContentType } from '@remirror/core';
import type { InvalidContentHandler, RemirrorJSON } from 'remirror';
import { AllStyledComponent } from '@remirror/styles/emotion';
import { BlockquoteExtension } from '@remirror/extension-blockquote';
import { BoldExtension } from '@remirror/extension-bold';
import { HardBreakExtension } from '@remirror/extension-hard-break';
import { HeadingExtension } from '@remirror/extension-heading';
import { HorizontalRuleExtension } from '@remirror/extension-horizontal-rule';
import { ItalicExtension } from '@remirror/extension-italic';
import { ParagraphExtension } from '@remirror/extension-paragraph';
import {
    BulletListExtension,
    OrderedListExtension,
    TaskListExtension,
} from '@remirror/extension-list';
import { StrikeExtension } from '@remirror/extension-strike';
import { UnderlineExtension } from '@remirror/extension-underline';
import { SubExtension } from '@remirror/extension-sub';
import { SupExtension } from '@remirror/extension-sup';
import { FontSizeExtension } from '@remirror/extension-font-size';
import { TextColorExtension } from '@remirror/extension-text-color';
import { TextHighlightExtension } from '@remirror/extension-text-highlight';
import { MarkdownExtension } from '@remirror/extension-markdown';
import { ReactComponentExtension } from '@remirror/extension-react-component';
import { TableExtension } from '@remirror/extension-react-tables';
import { CalloutExtension } from '@remirror/extension-callout';
import { IframeExtension } from "./editor/IframeExtension";
import { CodeExtension } from "./editor/CodeExtension";
import 'remirror/styles/all.css';
import "./DocPanel.css";

interface ReadOnlyEditorProps {
    content: RemirrorContentType;
};

const ReadOnlyEditor: React.FC<ReadOnlyEditorProps> = (props) => {
    let content = props.content;
    if (typeof content == 'string') {
        if (content.startsWith('{')) {
            try {
                content = JSON.parse(content) as RemirrorJSON;
                if (content.type == undefined) {
                    content.type = "doc";
                }
            } catch (err) {
            }
        }
    }

    const onError: InvalidContentHandler = useCallback(({ json, invalidContent, transformers }) => {
        // Automatically remove all invalid nodes and marks.
        return transformers.remove(json, invalidContent);
    }, []);

    const { manager, state } = useRemirror({
        content: content,
        extensions: () => {
            return [
                new ParagraphExtension(),
                new HardBreakExtension(),
                new HorizontalRuleExtension({}),
                new BlockquoteExtension(),
                new BoldExtension({ weight: 20 }),
                new BulletListExtension({}),
                new OrderedListExtension(),
                new TaskListExtension(),
                new IframeExtension(),
                new CodeExtension(),
                new MarkdownExtension({ copyAsMarkdown: false }),
                new HeadingExtension({ defaultLevel: 3, levels: [1, 2, 3, 4, 5, 6] }),
                new StrikeExtension(),
                new ItalicExtension(),
                new UnderlineExtension(),
                new SubExtension(),
                new SupExtension(),
                new FontSizeExtension({ defaultSize: '16', unit: 'px' }),
                new TextColorExtension({}),
                new TextHighlightExtension({}),
                new CalloutExtension({}),
                new ReactComponentExtension({}),
                new TableExtension({}),
            ];
        },
        stringHandler: 'html',
        onError: onError,
    });


    return (
        <div className="remirror-readonly">
            <ThemeProvider>
                <AllStyledComponent>
                    <Remirror manager={manager} initialContent={state} editable={false}>
                        <EditorComponent />
                    </Remirror>
                </AllStyledComponent>
            </ThemeProvider>
        </div>
    );
};

export interface DocPanelProps {
    shareInfo: ShareInfo;
}

export function DocPanel(props: DocPanelProps) {
    const [content, setContent] = useState("");
    const [errorMsg, setErrorMsg] = useState("");

    const loadDocContent = async () => {
        const res = await fetch(`/api/doc?id=${props.shareInfo.shareId}&secret=${props.shareInfo.shareSecret}`);
        const resData = await res.json() as {
            code: number;
            errMsg: string;
            doc: DocInfo;
        };
        if (resData.code == 0) {
            setContent(resData.doc.baseInfo?.content ?? "{}");
        } else {
            setErrorMsg(resData.errMsg);
        }
    };

    useEffect(() => {
        loadDocContent();
    }, []);

    return (
        <>
            {errorMsg != "" && errorMsg}
            {errorMsg == "" && content != "" && (
                <ReadOnlyEditor content={content} />
            )}
        </>
    )
}